#include "globals.h"
#include <iostream>

#include <GL/glut.h>
#include "tinyxml/tinyxml.h"

#include <string.h>
#include <stdio.h>

#include "menuscreen.h"
#include "menumanager.h"

struct menuButton;

CMenuManager::CMenuManager(int width, int height) {
	m_windowWidth = width;
	m_windowHeight = height;
	m_spaceTopBottom = 0;
	m_menuItemHeight=50;
	m_numberTopMenuItems = 0;
	m_spaceBetweenItems = 25;
	m_spaceLeftRight = 150;
//	m_screen[1].m_numberButtons = 0;
//	m_screen[2].m_numberButtons = 0;
	m_currentScreenNum = 1; //default screen //TODO: is 1 really the best choice here?
}

CMenuManager::~CMenuManager() {

}

void CMenuManager::updateWindowSize(int width, int height) {
	m_windowWidth = width;
	m_windowHeight = height;
}


void CMenuManager::createMenu(char *filename) {
	//TODO: scope of doc OK??
	TiXmlDocument doc( filename );
	if (!doc.LoadFile()) {
		LOG("XML load ERROR")
	}
	
	TiXmlElement *todoElement = 0;
//	TiXmlNode *node = 0;
	TiXmlElement* itemElement = 0;
	

	//xml: find Menu element
	todoElement = doc.FirstChildElement("Menu");
	assert( todoElement  );


	//iterate through "Screen" elements
	for( itemElement = todoElement->FirstChildElement("Screen"); 
	 itemElement; 
	 itemElement = itemElement->NextSiblingElement() )
	{
//		std::cout << "XML: Element text: " << itemElement->GetText() << std::endl;
		LOG("XML: Screen found! id = " << itemElement->Attribute( "id" ))
		LOG("-------------------")
	
		m_menuScreenList.push_back(new CMenuScreen(atoi(itemElement->Attribute( "id" ))));

		int tmp_screenid = atoi(itemElement->Attribute( "id" ));
		assert (tmp_screenid);
//		std::cout << "tmp_screenid = " << tmp_screenid << std::endl;

		int i=0;
		//iterate through "Item" elememts
		for( TiXmlElement *newitemElement = itemElement->FirstChildElement("Item"); 
		 newitemElement; 
		 newitemElement = newitemElement->NextSiblingElement() ){
				
				std::list<std::string> tmpOptionsList;
				std::string tmpDefaultSetting; 
			
			if (newitemElement->Attribute("defaultsetting")!=NULL) {
				tmpDefaultSetting =  newitemElement->Attribute("defaultsetting");
			}

			for (TiXmlElement *optionElement=newitemElement->FirstChildElement("Setting"); optionElement; optionElement = optionElement->NextSiblingElement() ) {
				//if (optionElement) LOG("option button discovered")
				LOG("option: " << optionElement->Attribute("value"))
				tmpOptionsList.push_back(optionElement->Attribute("value"));

			}
			

			//NOTE: addButton(int order, int followScreenID, string text
			//IDEA: let CMenuScreen object translate followScreenID
			//into pointer to other CMenuScreen object if necessary
			m_menuScreenList.back()->addButton(
			 atoi(newitemElement->Attribute( "order" )),
			 atoi(newitemElement->Attribute( "followScreenID" )),
			 newitemElement->GetText(),
			 //NOTE: default setting now becomes current setting!
			 tmpOptionsList, tmpDefaultSetting);

			i++;
		}

	}
}

void CMenuManager::printTopMenuItems(void) {
	std::list<std::string>::iterator it;
	std::cout << "number of elements: " << m_topMenuItems.size() << std::endl;
	for (it=m_topMenuItems.begin(); it!=m_topMenuItems.end(); it++) {
		std::cout << *it << std::endl;
	}
}


void CMenuManager::drawScreenItems() {
	//if no screen number is given
	//then draw the one set in m_currentScreenNum
	//(usually 1 per default)
	drawScreenItems(m_currentScreenNum);
}


void CMenuManager::drawScreenItems(int screenNum) {
	assert( screenNum > 0 );
	m_currentScreenNum = screenNum;
	int i = 0;
	std::list<std::string>::iterator it;

	//TODO: uncomment when menu is working
	glColor4f(0.0, 0.0, 0.0, 0.1);
	glBegin(GL_QUADS);
		glVertex2i(0, 0);
		glVertex2i(m_windowWidth, 0);
		glVertex2i(m_windowWidth, m_windowHeight);
		glVertex2i(0, m_windowHeight);
	glEnd();

//	std::cout << "m_spaceBetweenItems: " << m_spaceBetweenItems << std::endl;


//	itScreen=m_menuScreenList.begin();

	std::list<CMenuScreen*>::iterator itScreen;
	for (itScreen=m_menuScreenList.begin(); itScreen!=m_menuScreenList.end(); itScreen++) {
		
		if ((*itScreen)->getID()==screenNum) break;

	}
	
	
	
	

	int tmpNumberButtons = (*itScreen)->m_numberButtons;
	
	m_spaceTopBottom = (m_windowHeight - (tmpNumberButtons * m_menuItemHeight +
	 tmpNumberButtons * m_spaceBetweenItems))/2;

//	std::list<CMenuScreen::menuButton*> tmpMenuButtonList;

//	tmpMenuButtonList.assign((*itScreen)->menuButtonList.begin(), (*itScreen)->menuButtonList.end());

//	tmpMenuButtonList = (*itScreen)->menuButtonList;

//	tmpMenuButtonList = itScreen->getButtonList();

	std::list<CMenuScreen::menuButton*>::iterator itButtons;

//	itButtons=(*m_menuScreenList.begin())->menuButtonList.begin();
	for(itButtons=(*itScreen)->menuButtonList.begin(); 
	 itButtons!=(*itScreen)->menuButtonList.end();
	 itButtons++) {
		
//		std::cout << "YYYYYYY: " << (*itButtons)->text << std::endl;

//		std::cout << "button followID: " << (*itScreen)->getButtonFollowScreenID(*itButtons) << std::endl;

		(*itButtons)->x1 = m_spaceLeftRight;
		(*itButtons)->y1 = m_spaceTopBottom + (i * m_menuItemHeight) + 
		 (i * m_spaceBetweenItems);

		(*itButtons)->x2 = m_windowWidth - m_spaceLeftRight;
		(*itButtons)->y2 = m_spaceTopBottom + (i * m_menuItemHeight) +
		 (i * m_spaceBetweenItems);

		(*itButtons)->x3 = m_windowWidth - m_spaceLeftRight;
		(*itButtons)->y3 = m_menuItemHeight + m_spaceTopBottom + 
		 (i * m_menuItemHeight) + (i * m_spaceBetweenItems);

		(*itButtons)->x4 = m_spaceLeftRight;
		(*itButtons)->y4 = m_menuItemHeight + m_spaceTopBottom + 
		 (i * m_menuItemHeight) + (i * m_spaceBetweenItems);
	
		glColor4f(0.5, 0.5, 0.5, 0.1);
		glBegin(GL_QUADS);
			glVertex2i((*itButtons)->x1, (*itButtons)->y1);
			glVertex2i((*itButtons)->x2, (*itButtons)->y2);
			glVertex2i((*itButtons)->x3, (*itButtons)->y3);
			glVertex2i((*itButtons)->x4, (*itButtons)->y4);

		glEnd();
		

		//TODO: make separate function for text drawing
		//TODO: string has limited size: boundaries check!
		//TODO: change to C++ string!!
		char tmp[40];
		strcpy(tmp, (*itButtons)->text.c_str());
		if ((*itButtons)->availOptionsList.size()>0) {
			strcat(tmp, " = ");
			strcat(tmp, (*itButtons)->currentSetting.c_str());
		}
		
		glColor3f(1.0, 1.0, 1.0);
		//calculate x,y positions for Text
		glRasterPos2i(m_windowWidth/2 - (10*
		((*itButtons)->text.size() + (*itButtons)->currentSetting.size() +
		 3))/2,
		 m_spaceTopBottom + (i * m_menuItemHeight) + 
		 (i * m_spaceBetweenItems) + m_menuItemHeight/2 + 9);
		
		for (int j=0; tmp[j]!='\0'; j++) {
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, tmp[j]);
	//		cout << "i= " << i << endl;
		}
		i++;
	 }
	
}

CMenuScreen* CMenuManager::getCurrentScreen(void){
	std::list<CMenuScreen*>::iterator itScreen;
	for (itScreen=m_menuScreenList.begin(); itScreen!=m_menuScreenList.end(); itScreen++) {
		
		if ((*itScreen)->getID()==m_currentScreenNum) return *itScreen;
	}

	return 0;
}
